(ns logging
  (:require clojure.tools.logging))

;; XXX: don't use this one. Use clojure.tools.logging directly.

(defn to-message [m]
  (if-not (instance? Throwable m)
    m
    (let [sw (java.io.StringWriter.)
          pw (java.io.PrintWriter. sw)]
      (.printStackTrace m pw)
      (.toString sw))))


(defmacro log
  ([level message]
    `(clojure.tools.logging/log ~level (to-message ~message)))
  ([level message throwable]
    `(clojure.tools.logging/log ~level (to-message ~message) ~throwable))
  ([level message throwable log-ns]
    `(clojure.tools.logging/log ~level (to-message ~message) ~throwable ~log-ns)))

(defmacro trace
  ([message]
    `(clojure.tools.logging/trace (to-message ~message)))
  ([message throwable]
    `(clojure.tools.logging/trace (to-message ~message) ~throwable)))

(defmacro debug
  ([message]
    `(clojure.tools.logging/debug (to-message ~message)))
  ([message throwable]
    `(clojure.tools.logging/debug (to-message ~message) ~throwable)))

(defmacro info
  ([message]
    `(clojure.tools.logging/info (to-message ~message)))
  ([message throwable]
    `(clojure.tools.logging/info (to-message ~message) ~throwable)))

(defmacro warn
  ([message]
    `(clojure.tools.logging/warn (to-message ~message)))
  ([message throwable]
    `(clojure.tools.logging/warn (to-message ~message) ~throwable)))

(defmacro error
  ([message]
    `(clojure.tools.logging/error (to-message ~message)))
  ([message throwable]
    `(clojure.tools.logging/error (to-message ~message) ~throwable)))

(defmacro fatal
  ([message]
    `(clojure.tools.logging/fatal (to-message ~message)))
  ([message throwable]
    `(clojure.tools.logging/fatal (to-message ~message) ~throwable)))

;(defmacro exception
;  ([message]
;    `(clojure.tools.logging/exception (to-message ~message)))
;  ([message throwable]
;    `(clojure.tools.logging/exception (to-message ~message) ~throwable)))

;(def #^{:macro true} exception #'error)


;; TODO: redirect STDOUT/STDERR to logger.

(defn redirect-stream [stream log-ns]
  (proxy [java.io.PrintStream] [stream]
    (print
      [#^String s]
      (log :info (str ">>" s) nil log-ns))))


(System/setOut (redirect-stream System/out "STDOUT")) ; doesn't work???

;(println "stdout?")

